package com.zxm.redis;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.sound.midi.VoiceStatus;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.context.Theme;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;

public class RedisClusterUtil {

	//使用TreadLocal保证线程安全
	private static ThreadLocal<Map<Object, Transaction>> threadLocal = new ThreadLocal<>();

	/**
	 * 将值添加到缓存队列List中
	 * key: 在redis中存红包的key
	 * keys:所有红包的key
	 */
	public static void lpush(String key,String...keys) {
		Map<Object,Transaction > map = threadLocal.get();
		if(keys!=null && keys.length>0) {
			Transaction tx = map.get(key);
			tx.lpush(key, keys);
		}
	}

	/**
	 * 将数据添加到sorted set中
	 * 将数据添加到事务中
	 */
	public static void zadd(String key,Map<String, Double> scoreMembers) {
		Map<Object, Transaction> map = threadLocal.get();
		if(scoreMembers!=null) {
			Transaction tx = map.get(key);
			tx.zadd(key, scoreMembers);
		}
	}


	/**
	 * 开启事务
	 * 所要操作的属性可能会分布在不同的节点上，
	 * 所有要要根据所有的key来找到不同的key分布在哪个节点上
	 * 然后将key所在的所有节点都开事务
	 */
	public static void multi(JedisCluster jedisCluster,String...keys) {
		//从threadLocal中获取事务
		Map<Object,Transaction> map = threadLocal.get();
		if(map ==null ) {
			map = new HashMap<>();
			threadLocal.set(map);
		}
		//获取所有节点的信息
		Map<String, JedisPool> nodes = jedisCluster.getClusterNodes();
		for(Entry<String, JedisPool> entry:nodes.entrySet()) {
			String hostAndPort = entry.getKey();
			//按冒号分割
			String[] arr = hostAndPort.split(":");
			String host = arr[0];
			Integer post = Integer.valueOf(arr[1]);
			Jedis jedis = new Jedis(host,post);
			if(keys!=null && keys.length>0) {
				for(String key:keys) {
					try {
						//key只会存在集群中的一个节点中
						jedis.exists(key);
						//开启事务
						Transaction tx = jedis.multi();
						map.put(key, tx);
					}catch(Exception e) {
						System.out.println("----none----");
					}
				}
			}
		}
	}

	/**
	 * 设置值
	 * 约定下标为偶数的时候为key
	 * 下标为奇数的时候为value
	 */
	public static void set(JedisCluster jedisCluster,String... keyValues) {
		//从threadLocal中获取map
		Map<Object, Transaction> map = threadLocal.get();
		if(keyValues!=null && keyValues.length>0) {
			for(int i=0;i<keyValues.length;i+=2) {
				String key = keyValues[i];
				String value = keyValues[i+1];
				Transaction tx = map.get(key);
				tx.set(key, value);
			}
		}
	}

	public static void hset(String hashKey,String field,String value) {
		//从threadLocal中获取map
		Map<Object, Transaction> map = threadLocal.get();
		Transaction tx = map.get(hashKey);
		tx.hset(hashKey, field, value);
	}
	
	/**
	 * 提交事务 将所有事务都要提交
	 */
	public static void exec() {
		Map<Object, Transaction> map = threadLocal.get();
		for(Entry<Object, Transaction> m:map.entrySet()) {
			Transaction tx = m.getValue();
			//提交
			tx.exec();
		}
		threadLocal.remove();
	}

	/**
	 * 回滚事务
	 */
	public static void discard() {
		Map<Object, Transaction> map = threadLocal.get();
		for(Entry<Object, Transaction> m:map.entrySet()) {
			Transaction tx = m.getValue();
			//提交
			tx.discard();
		}
		threadLocal.remove();
	}

}
